package com.yanqu.road.server.manager;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.data.analytics.Provider;
import com.yanqu.data.analytics.ProviderFactory;
import com.yanqu.data.analytics.constant.EventDataConstants;
import com.yanqu.data.analytics.helper.DataBuilder;
import com.yanqu.data.analytics.impl.EmptyProvider;
import com.yanqu.road.entity.enums.eBigRankType;
import com.yanqu.road.entity.servercenter.ChannelInfo;
import com.yanqu.road.entity.servercenter.DAServerInfo;
import com.yanqu.road.entity.union.cross.CrossUnionInfo;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.entity.union.huaben.UnionHuaBenPassWeekData;
import com.yanqu.road.logic.cross.CrossGroupRankListModel;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.manager.rank.CrossRankMgr;
import com.yanqu.road.server.manager.union.CrossUnionConfigMgr;
import com.yanqu.road.server.manager.union.CrossUnionMgr;
import com.yanqu.road.server.manager.union.huaben.CrossUnionHuaBenConfigMgr;
import com.yanqu.road.server.manager.union.huaben.CrossUnionHuaBenMgr;
import com.yanqu.road.server.manger.CrossUnionServerGroupMgr;
import com.yanqu.road.server.manger.DAServerListMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 分组跨服-数据埋点管理
 */
public class CrossDataAnalyticsMgr extends TempMgr {

    private static Logger logger = LogManager.getLogger(CrossDataAnalyticsMgr.class.getName());

    public static Provider provider = new EmptyProvider(logger);

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        //渠道
        int channelId = ConfigHelper.getInt("channelId");
        ChannelInfo channelInfo = ServerListMgr.getChannelInfo(channelId);
        if(channelInfo == null){
            return false;
        }
        Provider old = provider;
        if(initDataAnalytics()) {
            if(channelInfo.getKafkaCollect() == 1){
                provider = ProviderFactory.getProvider("KAFKA", logger, channelInfo.getKafkaServers());
            }else if(!StringUtils.isNullOrEmpty(channelInfo.getCollectServerUrl())) {
                provider = ProviderFactory.getProvider("TDA", logger, channelInfo.getCollectServerUrl());
            }
        }else {
            provider = new EmptyProvider(logger);
        }
        old.flush();
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        if(provider != null) {
            provider.flush();
            provider.close();
        }
        return true;
    }

    /**
     * 是否开启埋点
     */
    public static boolean openDataAnalytics(){
        if(provider.getClass().getSimpleName().equals("EmptyProvider")){
            return false;
        }
        return true;
    }

    private static boolean initDataAnalytics(){
        //渠道
        int channelId = ConfigHelper.getInt("channelId");
        ChannelInfo channelInfo = ServerListMgr.getChannelInfo(channelId);
        if(channelInfo == null){
            return false;
        }
        if(!channelInfo.isOpenDataAnalytics()){
            return false;
        }
        DAServerInfo daServerInfo = DAServerListMgr.get(channelInfo.getChannelId(), ConfigHelper.getInt("serverId"));
        if(daServerInfo == null){
            return false;
        }
        return true;
    }

    /**
     * 分组榜单
     */
    public static void trackCrossUserRankEvent() {

        if (!openDataAnalytics()) return;

        List<Integer> bigTypeList = new ArrayList<>();
        bigTypeList.add(eBigRankType.Normal.getValue());
        bigTypeList.add(eBigRankType.Skin.getValue());
        bigTypeList.add(eBigRankType.Vehicle.getValue());
        bigTypeList.add(eBigRankType.Patrons.getValue());
        bigTypeList.add(eBigRankType.Beauty.getValue());

        for (Map.Entry<Integer, Map<Integer, Map<Integer, CrossGroupRankListModel>>> groupEntry : CrossRankMgr.getAllCrossGroupRankListModelMap().entrySet()) {
            int groupId = groupEntry.getKey();
            for (Map.Entry<Integer, Map<Integer, CrossGroupRankListModel>> bigEntry : groupEntry.getValue().entrySet()) {

                //先刷下上报
                CrossDataAnalyticsMgr.provider.flush();

                int bigType = bigEntry.getKey();
                if(!bigTypeList.contains(bigType)){
                    continue;
                }
                for (Map.Entry<Integer, CrossGroupRankListModel> modelEntry : bigEntry.getValue().entrySet()) {
                    int rankType = modelEntry.getKey();
                    CrossGroupRankListModel listModel = modelEntry.getValue();

                    try{
                        DataBuilder dataBuilder = DataBuilder.newBuilder(EventDataConstants.Rank.RANK_ACCOUNT_ID, "");
                        dataBuilder.build(EventDataConstants.Rank.GROUP_ID, "" + groupId);
                        dataBuilder.build(EventDataConstants.Rank.RANK_TYPE_ONE, bigType);
                        dataBuilder.build(EventDataConstants.Rank.RANK_TYPE_TWO, rankType);
                        List<RankProto.RankTempMsg> list = listModel.getRankListMsg().getRankListList();

                        JSONArray array = new JSONArray();
                        int size = list.size();
                        for (int i = 0; i < size && i < EventDataConstants.ARRAY_OBJECT_MAX_SIZE; i++) {
                            RankProto.RankTempMsg rank = list.get(i);
                            JSONObject object = new JSONObject();
                            object.put("Ranking", i + 1);
                            object.put("userid", rank.getUserId());
                            object.put("List_value", rank.getValue());
                            array.add(object);
                        }
                        dataBuilder.build(EventDataConstants.Rank.RANK, array);
                        provider.track(dataBuilder.getAccountId(), dataBuilder.getDistinctId(), EventDataConstants.Rank.ALL_RANK_EVENT, dataBuilder.getDataMap());
                    }catch (Exception e){
                        logger.error("analytics trackUserRankEvent error {},{} ", bigType, rankType, e);
                    }
                }
            }
        }
        logger.debug("trackCrossUserRankEvent finish");
    }

    /**
     * 商会快照
     */
    public static void trackCrossUnionSnapshot(){
        //0点上报活跃商会
        try {
            if (!openDataAnalytics()) return;

            int count = 0;

            for (Map.Entry<String, CrossUnionInfo> unionInfoEntry : CrossUnionMgr.getUnionInfoMap().entrySet()) {

                CrossUnionInfo crossUnionInfo = unionInfoEntry.getValue();
                if (crossUnionInfo.isDelete()) {
                    continue;
                }
                Map<Long, CrossUnionMember> memberMap = CrossUnionMgr.getUnionMemberMap(crossUnionInfo.getUnionUid());
                if(memberMap == null){
                    continue;
                }
                boolean isActive = false;
                for (Map.Entry<Long, CrossUnionMember> memberEntry : memberMap.entrySet()) {
                    CrossUnionMember member = memberEntry.getValue();
                    if(member.getCacheTodayContribution() > 0 || member.getTodayContribution() > 0){
                        isActive = true;
                        break;
                    }
                }
                if(!isActive){
                    continue;
                }

                DataBuilder dataBuilder = DataBuilder.newBuilder(EventDataConstants.Union.GUILD_ACCOUNT_ID, "");
                dataBuilder.build(EventDataConstants.Rank.SERVER_ID, crossUnionInfo.getServerId());
                dataBuilder.build(EventDataConstants.Union.GUILD_LEVEL, CrossUnionConfigMgr.getUnionLv(crossUnionInfo.getExperience()));
                dataBuilder.build(EventDataConstants.Union.GUILD_ID, crossUnionInfo.getUnionUid());
                dataBuilder.build("GUILD_NUM", crossUnionInfo.getMemberCount());
                dataBuilder.build(EventDataConstants.Union.GUILD_NAME, crossUnionInfo.getUnionName());
                dataBuilder.build(EventDataConstants.Union.GUILD_SPEED, crossUnionInfo.getTotalEarnSpeed().longValue());
                int groupId = CrossUnionServerGroupMgr.getGroupIdByServerId(crossUnionInfo.getServerId());
                List<Long> groupServerList = new ArrayList<>(CrossUnionServerGroupMgr.getGroupServer(groupId));
                dataBuilder.build(EventDataConstants.Union.GUILD_CROSSSERVER, groupServerList);
                //话本
                int thisWeekId = CrossUnionHuaBenConfigMgr.getThisWeekId();
                UnionHuaBenPassWeekData passWeekData = CrossUnionHuaBenMgr.getUnionHuaBenPassWeekData(thisWeekId, crossUnionInfo.getServerId(), crossUnionInfo.getUnionUid());
                if(passWeekData != null){
                    dataBuilder.build(EventDataConstants.Union.GUILD_STORY, passWeekData.getDegree());
                }
                //门客赚钱
                BigInteger patronsTotalEarnSpeed = BigInteger.ZERO;
                for (Map.Entry<Long, CrossUnionMember> memberEntry : memberMap.entrySet()) {
                    CrossUnionMember member = memberEntry.getValue();
                    patronsTotalEarnSpeed = patronsTotalEarnSpeed.add(member.getUserBaseInfo().getTotalAbility());
                }
                dataBuilder.build(EventDataConstants.Union.GUILD_MINISTERPOWER, patronsTotalEarnSpeed.toString());
                provider.track(dataBuilder.getAccountId(), dataBuilder.getDistinctId(), EventDataConstants.Union.GUILD, dataBuilder.getDataMap());

                count++;
                if(count >= 2000){
                    CrossDataAnalyticsMgr.provider.flush();
                    count = 0;
                }
            }

        }catch (Exception e){
            getLogger().info("error", e);
        }

    }
}
